# coding=utf-8
"""

3. 安装ImageWatch，并在代码中通过设置断点，观察处理中间结果图像
结果分析：
1) 直接以下一题(第四题)的执行过程来测试ImageWatch的功能，测试视频（vtest.avi）共有 795 帧
2) 任意中断执行并截图(含特征点光流估计: 利用圆圈和短直线显示移动向量)
https://gitee.com/skyrookieyu/csdn_ai25_week3/blob/master/IW_1.JPG
https://gitee.com/skyrookieyu/csdn_ai25_week3/blob/master/IW_2.JPG
https://gitee.com/skyrookieyu/csdn_ai25_week3/blob/master/IW_3.JPG
https://gitee.com/skyrookieyu/csdn_ai25_week3/blob/master/IW_4.JPG
https://gitee.com/skyrookieyu/csdn_ai25_week3/blob/master/IW_5.JPG
https://gitee.com/skyrookieyu/csdn_ai25_week3/blob/master/IW_6.JPG
3) 一开始没有特别去设定 goodFeaturesToTrack 和 calcOpticalFlowPyrLK 的参数，直接套用缺省的参数，结果跑出来的效果很不好，后来把老师在课堂上示范的 Python 版本参数套进去就有很好的效果，可见处理影像和视频资料必须针对该影像和视频的特性调整参数才行。

"""
"""

#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using namespace std;

#define MAX_POINT_COUNT 300

int main()
{
	char fn[] = "vtest.avi";
	VideoCapture cap;
	Mat source, result, gray, lastGray;
	vector<Point2f> points[2], temp;
	vector<uchar> status;
	vector<float> err;

	cap.open(fn);
	if (!cap.isOpened())
	{
		cout << "Can't open video!" << endl;
		return -1;
	}

	for (;;)
	{
		cap >> source;
		if (source.empty())
			break;

		cvtColor(source, gray, COLOR_BGR2GRAY);
		if (points[0].size() < 10)
		{
			goodFeaturesToTrack(gray, points[0], MAX_POINT_COUNT, 0.3, 7, noArray(), 7);
		}

		if (lastGray.empty())
			gray.copyTo(lastGray);

		// Using parameters in class materials
		calcOpticalFlowPyrLK(lastGray, gray, points[0], points[1], status, err, cv::Size(15, 15), 2, cv::TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 0.03));

		int counter = 0;
		
		for (int i = 0; i < points[1].size(); i++)
		{
			double dist = norm(points[1][i] - points[0][i]);
			if (status[i] && dist >= 2.0 && dist <= 20.0)
			{
				points[0][counter] = points[0][i];
				points[1][counter++] = points[1][i];
			}

		}
		points[0].resize(counter);
		points[1].resize(counter);

		source.copyTo(result);
		for (int i = 0; i < points[1].size(); i++)
		{
			line(result, points[0][i], points[1][i], Scalar(0, 0, 0xff), 3);
			circle(result, points[1][i], 3, Scalar(0, 0xff, 0));
		}

		swap(points[0], points[1]);
		swap(lastGray, gray);

		//imshow("source", source);
		imshow("result", result);
             
		char key = waitKey(27);
		if (key == 27)
			break;
		

	}
	cap.release();
	destroyAllWindows();
	return 0;
}

"""